package com.heima.comment.service.imp;

import com.heima.aliyun.GreenTextScan;
import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustomException;
import com.heima.feigns.user.UserFeign;
import com.heima.model.comment.dto.CommentDto;
import com.heima.model.comment.dto.CommentLikeDto;
import com.heima.model.comment.dto.CommentSaveDto;
import com.heima.model.comment.pojo.ApComment;
import com.heima.model.comment.pojo.ApCommentLike;
import com.heima.model.comment.vo.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojo.ApUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author TheCai
 * @date 2021/6/5 19:39
 */
@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

  @Autowired UserFeign userFeign;

  @Autowired GreenTextScan greenTextScan;

  @Autowired MongoTemplate mongoTemplate;

  @Autowired CommentHotService commentHotService;
  /**
   * 保存评论
   *
   * @param dto
   * @return
   */
  @Override
  public ResponseResult saveComment(CommentSaveDto dto) {

    // 1.检查参数(文章id,评论内不能大于140字符 ,是否登录),已在实体类中写好了
    ApUser user = AppThreadLocalUtils.getUser();
    if (user == null) {
      return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
    }
    // 2.远程获取登录用户信息
    user = userFeign.findUserById(user.getId());
    if (user == null) {
      throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST, "未获取到用户id");
    }
    // 3.阿里云文本检查
    boolean isTextScan = handleTextScan(dto.getContent()); // 阿里云文本审核
    if (!isTextScan) {
      return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论内容不符合要求,请重新编辑");
    }
    ;
    log.info("=======当前处理的文章通过阿里云文本审核======当前处理的文章id======= {}", dto.getArticleId());

    // 4.保存评论信息
    ApComment apComment = new ApComment();
    apComment.setAuthorId(user.getId());
    apComment.setAuthorName(user.getName());
    apComment.setEntryId(dto.getArticleId()); // 这里的entryid是文章id
    apComment.setType((short) 0);
    apComment.setContent(dto.getContent());
    apComment.setImage(user.getImage());
    apComment.setLikes(0);
    apComment.setReply(0);
    apComment.setFlag((short) 0);
    apComment.setCreatedTime(new Date());
    apComment.setUpdatedTime(new Date());

    mongoTemplate.insert(apComment);

    return ResponseResult.okResult();
  }

  /**
   * 点赞评论
   *
   * @param dto
   * @return
   */
  @Override
  public ResponseResult like(CommentLikeDto dto) {
    // 1.检查参数(评论id  方式  是否登录)
    ApUser user = AppThreadLocalUtils.getUser();
    if (user == null) {
      return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
    }
    // 2.根据评论id查询评论信息
    ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);

    if (apComment == null) {
      throw new CustomException(AppHttpCodeEnum.SERVER_ERROR);
    }

    // 保证不会重复点赞
    Query query =
        Query.query(
            Criteria.where("authorId").is(user.getId()).and("commentId").is(dto.getCommentId()));
    ApCommentLike apCommentLike = mongoTemplate.findOne(query, ApCommentLike.class);
    if (apCommentLike != null && dto.getOperation().intValue() == 0) {
      return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST, "已点赞");
    }

    // 3.如果方式为0代表点赞
    if (dto.getOperation().intValue() == 0) {
      // 评论点赞数+1
      apComment.setLikes(apComment.getLikes() + 1);
      // 添加评论点赞信息
      apCommentLike = new ApCommentLike();
      apCommentLike.setAuthorId(user.getId());
      apCommentLike.setCommentId(apComment.getId());
      apCommentLike.setOperation(dto.getOperation());
      // 插入数据,也就点赞成功了
      mongoTemplate.insert(apCommentLike);

      // 如果点赞大于等于五 的 普通评论(Flag=0)
      if (apComment.getLikes() >= 5 && apComment.getFlag().intValue() == 0) {
        // 有资格计算热点评论
        commentHotService.hotCommentExecutor(apComment);
      }

    } else {
      // 4.如果方式为1代表取消点赞
      // 评论点赞数-1
      apComment.setLikes(apComment.getLikes() <= 0 ? 0 : (apComment.getLikes() - 1));

      // 删除评论点赞信息
      mongoTemplate.remove(query, ApCommentLike.class);
    }

    // 返回点赞数量 : likes

    Map map = new HashMap();
    map.put("likes", apComment.getLikes());

    return ResponseResult.okResult(map);
  }

  /**
   * 根据文章id查询评论列表
   *
   * @return
   */
  @Override
  public ResponseResult findByArticleId(CommentDto dto) {
    // 1.检查参数(文章ID  最小时间 分页10条)
    dto.checkParam();

    List<ApComment> apComments;
    // TODO 因为热点评论需要改造一下 ,就是index是1的时候

    // 查询首页需要热点评论
    if (dto.getIndex().intValue() == 1) {
      // 先查询热点评论
      Query hotQuery =
          Query.query(
                  Criteria.where("entryId")
                      .is(dto.getArticleId())
                      .and("createdTime")
                      .lt(dto.getMinDate())
                      .and("flag")
                      .is(1))
              .with(Sort.by(Sort.Direction.DESC, "likes"))
              .limit(dto.getSize());

      apComments = mongoTemplate.find(hotQuery, ApComment.class);
      if (apComments != null && apComments.size() > 0) {
        Query query =
            Query.query(
                    Criteria.where("entryId")
                        .is(dto.getArticleId())
                        .and("createdTime")
                        .lt(dto.getMinDate())
                        .and("flag")
                        .is(0))
                .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                .limit(dto.getSize() - apComments.size());
        List<ApComment> normalList = mongoTemplate.find(query, ApComment.class);
        apComments.addAll(normalList);
      } else {
        // 如果热点评论为空的话和普通查询一样
        Query query =
            Query.query(
                    Criteria.where("entryId")
                        .is(dto.getArticleId())
                        .and("createdTime")
                        .lt(dto.getMinDate())
                        .and("flag")
                        .is(0))
                .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                .limit(dto.getSize());
        apComments = mongoTemplate.find(query, ApComment.class);
      }

    } else {
      // 直接查询普通评论
      // 2.查询评论数据  articleid = ? , and createdTime<minDate
      Query query =
          Query.query(
                  Criteria.where("entryId")
                      .is(dto.getArticleId())
                      .and("createdTime")
                      .lt(dto.getMinDate())
                      .and("flag")
                      .is(0))
              .with(Sort.by(Sort.Direction.DESC, "createdTime"))
              .limit(dto.getSize());
      apComments = mongoTemplate.find(query, ApComment.class);
    }

    // 3.判断用户有没有登录
    ApUser user = AppThreadLocalUtils.getUser();
    if (user == null || apComments == null || apComments.size() == 0) {
      // 3.1没登录直接封装结果返回
      return ResponseResult.okResult(apComments);
    }
    // 3.2如果登录了.查看当前分页的评论信息,哪些评论点过赞, ApComment -> ApCommentVo
    // 要去ApCommentLike里查点赞(userid  commentid(有多个所以要in) )

    List<String> apCommentsIds =
        apComments.stream().map(ApComment::getId).collect(Collectors.toList());

    Query apCommentLikeQuery =
        Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").in(apCommentsIds));
    // 在当前分页数据下,登录用户所点赞过得所有数据
    List<ApCommentLike> apCommentLikes =
        mongoTemplate.find(apCommentLikeQuery, ApCommentLike.class);
    // 这里抽取的是点赞里的评论id,这样我们就得到了点过赞的评论ID
    List<String> likeCommentIds =
        apCommentLikes.stream().map(ApCommentLike::getCommentId).collect(Collectors.toList());

    List<ApCommentVo> apCommentVoList = new ArrayList<>();
    // 把ApComment -> ApCommentVo
    apComments.forEach(
        apComment -> {
          ApCommentVo apCommentVo = new ApCommentVo();
          BeanUtils.copyProperties(apComment, apCommentVo);
          // 查看当前评论是否被点过赞,相当于标记一下点过赞的评论,前端特殊处理一下
          if (likeCommentIds.contains(apComment.getId())) {
            apCommentVo.setOperation((short) 0);
          }
          apCommentVoList.add(apCommentVo);
        });
    // 4.返回数据

    return ResponseResult.okResult(apCommentVoList);
  }

  /**
   * 阿里云文本审核
   *
   * @param
   * @return
   */
  private boolean handleTextScan(String text) {
    Boolean flag = false;
    try {
      Map map = greenTextScan.greenTextScan(text);
      // 阿里云给出的审核结果,建议
      String suggestion = map.get("suggestion").toString();
      System.out.println(suggestion);
      if ("pass".equals(suggestion)) {
        // 只有pass通过,其他一律不让过
        flag = true;
      }
    } catch (Exception e) {
      e.printStackTrace();
      flag = false;
    }
    return flag;
  }
}
